home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / Papers / Downs.FileSystem / source / patch / FilePatches.c next >
Encoding:
C/C++ Source or Header  |  1999-06-24  |  9.5 KB  |  395 lines  |  [TEXT/CWIE]

  1. //    Header files we may need.
  2. #include    <Finder.h>
  3. #include    <Folders.h>
  4. #include    <Gestalt.h>
  5. #include    <OSUtils.h>
  6. #include    <Packages.h>
  7. #include    <Traps.h>
  8.  
  9. #include    "FilePatches.h"
  10.  
  11. #ifndef powerc
  12.     #ifdef THINK_C
  13.         #pragma parameter __D0 SetA4(__D0)
  14.         pascal long SetA4(long newA4) = 0xC18C;
  15.     
  16.         #define SetCurrentA4() SetA4((long)&main)
  17.     #else
  18.         #include <A4Stuff.h>
  19.     #endif
  20. #else
  21.     #define SetCurrentA4() 0
  22.     #define SetA4(x) 0
  23.  
  24.     ProcInfoType __procinfo = kCStackBased
  25.              | RESULT_SIZE(kNoByteCode);
  26.  
  27.     ProcInfoType uppPBFileProcInfo = kRegisterBased
  28.              | RESULT_SIZE( kTwoByteCode )
  29.              | REGISTER_RESULT_LOCATION( kRegisterD0 )
  30.              | REGISTER_ROUTINE_PARAMETER( 1, kRegisterA0, kFourByteCode );
  31.  
  32. #endif
  33.  
  34.  
  35. /**************************
  36.     main
  37. **************************/
  38.  
  39. void        main( void )
  40. {
  41.     long        oldA4;
  42.     long        sysVersion;
  43.     OSErr        theError;
  44.     THz            oldZone;
  45.  
  46. #ifdef powerc
  47.     UniversalProcPtr    newPBHCreateAsyncAddress;
  48.  
  49.     UniversalProcPtr    newPBHCreateSyncAddress;
  50. #endif
  51.  
  52.     // Set up A4, so we can access our globals.
  53.     oldA4 = SetCurrentA4();
  54.  
  55.     oldZone = GetZone();
  56.     SetZone( SystemZone() );
  57.  
  58.     // We need to detach our code, so that we stay around.
  59.     DetachResource( GetResource( INIT_RES_TYPE, BASE_RES_ID ) );
  60.  
  61.     Gestalt( gestaltSystemVersion, &sysVersion );
  62.  
  63.     //    We require System 7.
  64.     if ( sysVersion >= MIN_SYSTEM_VERSION )
  65.     {
  66.             gParamBlockCopy = ( HParmBlkPtr )NewPtr( sizeof( HFileParam ) );
  67.             if ( gParamBlockCopy == NIL )
  68.                 goto justExit;
  69.  
  70.             gTempStringPtr = ( StringPtr )NewPtr( STRING_LENGTH );
  71.             if ( gTempStringPtr == NIL )
  72.                 goto justExit;
  73.  
  74. #ifndef powerc
  75.             //    Register our Gestalt routine, so the backgrounder can call in.
  76.             theError = NewGestalt( FS_SIGNATURE, ( SelectorFunctionUPP )DoFSPatchGestalt );
  77. #else
  78.             myGestaltUPP = NewSelectorFunctionProc( DoFSPatchGestalt );
  79.             theError = NewGestalt( FS_SIGNATURE, myGestaltUPP );
  80. #endif
  81.  
  82.             if ( theError != noErr )
  83.                 goto justExit;
  84.  
  85.             gFSPatchProcPtr = ( ProcPtr )&DoFSPatchGestalt;
  86.  
  87.             //    Standard patch stuff.
  88.             oldPBHCreateSyncAddress = ( PBHProc ) ( ( long )GetOSTrapAddress( _PBHCreateSync ) );
  89.  
  90. #ifndef powerc
  91.             SetOSTrapAddress( ( UniversalProcPtr )MyPBHCreateAsync, _PBHCreateSync );
  92. #else
  93.             newPBHCreateSyncAddress = NewRoutineDescriptor( ( ProcPtr )&MyPBHCreateSync, uppPBFileProcInfo, GetCurrentISA() );
  94.             if ( newPBHCreateSyncAddress == 0 )
  95.                 goto justExit;
  96.  
  97.             SetOSTrapAddress( newPBHCreateSyncAddress, _PBHCreateSync );
  98. #endif
  99.     }
  100.  
  101. justExit:
  102.     // Restore the old zone again
  103.     SetZone(oldZone);
  104.  
  105.     //    Required teardown.
  106.     SetA4(oldA4);
  107. }
  108.  
  109.  
  110. /**************************
  111.     MyPBHCreateSync
  112. **************************/
  113.  
  114. #ifndef powerc
  115. asm    void        MyPBHCreateSync( HParmBlkPtr paramBlock )
  116. {
  117.     MacroPreProcess
  118.  
  119.     move.w    kPBHCreateSync, -( sp );
  120.  
  121.     MacroSaveValues
  122.  
  123.     move.l    oldPBHCreateSyncAddress, a1;
  124.  
  125.     MacroCallOriginalTrap
  126. }
  127. #else
  128. OSErr        MyPBHCreateSync( HParmBlkPtr paramBlock )
  129. {
  130.     OSErr    theResult;
  131.  
  132.     CopyHParamBlockValues( paramBlock, kPBHCreateSync );
  133.  
  134.     theResult = CallOSTrapUniversalProc( ( UniversalProcPtr )oldPBHCreateSyncAddress, uppPBFileProcInfo, paramBlock );
  135.     
  136.     if ( theResult == noErr )
  137.         SetArrayElement();
  138.  
  139.     return theResult;
  140. }
  141. #endif
  142.  
  143.  
  144. /**************************
  145.     CopyHParamBlockValues
  146. **************************/
  147.  
  148. void        CopyHParamBlockValues( HParmBlkPtr paramBlock, short theTrapId )
  149. {
  150.  
  151. #ifdef __DEBUG__
  152.     DebugStr( "\pInside CopyHParamBlockValues()..." );
  153. #endif
  154.     
  155.     // Is this field valid?
  156.     gParamBlockCopy->fileParam.ioTrap = paramBlock->fileParam.ioTrap;
  157.  
  158.     gParamBlockCopy->fileParam.ioTrap = theTrapId;
  159.     gParamBlockCopy->fileParam.ioVRefNum = paramBlock->fileParam.ioVRefNum;
  160.     gParamBlockCopy->fileParam.ioDirID = paramBlock->fileParam.ioDirID;
  161.     gParamBlockCopy->fileParam.ioFlFndrInfo.fdType = paramBlock->fileParam.ioFlFndrInfo.fdType;
  162.     gParamBlockCopy->fileParam.ioNamePtr = paramBlock->fileParam.ioNamePtr;
  163. }
  164.  
  165.  
  166. /**************************
  167.     SetArrayElement
  168. **************************/
  169.  
  170. void        SetArrayElement( void )
  171. {
  172.     short        count = 0, max = 0;
  173.     FSPatchGlobalsPtr paramBlockCopy = nil;
  174.     FWData        theFWData;
  175.  
  176. #ifdef __DEBUG__
  177.     short        trap = 0;
  178. #endif
  179.  
  180.     SendAppleEvent();
  181.  
  182.     theFWData.theTrapId = gParamBlockCopy->fileParam.ioTrap;
  183.     theFWData.theVRefNum = gParamBlockCopy->fileParam.ioVRefNum;
  184.     theFWData.theParID = gParamBlockCopy->fileParam.ioDirID;
  185.     theFWData.theFileType = gParamBlockCopy->fileParam.ioFlFndrInfo.fdType;
  186.  
  187.     count = 0;
  188.     max = gParamBlockCopy->fileParam.ioNamePtr[ 0 ];
  189.  
  190.     while ( count <= max ) {
  191.         theFWData.theString[ count ] = gParamBlockCopy->fileParam.ioNamePtr[ count ];
  192.         count++;
  193.     }
  194.  
  195. #ifdef __DEBUG__
  196.     DebugStr( "\pInside SetArrayElement()..." );
  197. #endif
  198.  
  199. #ifdef __DEBUG__
  200.     trap = gParamBlockCopy->fileParam.ioTrap;
  201. #endif
  202.  
  203. //    if ( gCallbackProcPtr != 0L ) {
  204.     if ( ( gParamBlockCopy->fileParam.ioTrap == 0xFFFFA208 ) && gCallbackProcPtr != 0L ) {
  205. #ifdef __DEBUG__
  206.         DebugStr( "\pCalling callback from patch..." );
  207. #endif
  208.         CallUniversalProc( gCallbackProcPtr, uppCreateFileProcInfo, theFWData );
  209.     }
  210.  
  211.     //    Added by ASD on 01/28/99.
  212.     //    Get next free element.
  213.     //    If it doesn't exist, get out.
  214.     paramBlockCopy = ( FSPatchGlobalsPtr )PopAtomicStack( &gInputStack );
  215.     if ( !paramBlockCopy )
  216.         return;
  217.  
  218.     //    Copy PBRec data to new element.
  219.     //    Don't forget the trap id.
  220.     paramBlockCopy->theTrapId = gParamBlockCopy->fileParam.ioTrap;
  221.     paramBlockCopy->theVRefNum = gParamBlockCopy->fileParam.ioVRefNum;
  222.     paramBlockCopy->theParID = gParamBlockCopy->fileParam.ioDirID;
  223.     paramBlockCopy->theFileType = gParamBlockCopy->fileParam.ioFlFndrInfo.fdType;
  224.  
  225.     //    Save the Str255 temporary parameter copy.
  226.     count = 0;
  227.     max = gParamBlockCopy->fileParam.ioNamePtr[ 0 ];
  228.  
  229.     while ( count <= max ) {
  230.         paramBlockCopy->theString[ count ] = gParamBlockCopy->fileParam.ioNamePtr[ count ];
  231.         count++;
  232.     }
  233. }
  234.  
  235.  
  236. /**************************
  237.     SendAppleEvent
  238. **************************/
  239.  
  240. void        SendAppleEvent( void )
  241. {
  242.     AEAddressDesc        theAddressDesc;
  243.     AppleEvent            theAppleEvent, theReply;
  244.     Boolean                foundBackgroundApp;
  245.     FSSpec                theSpec;
  246.     OSErr                theError;
  247.     ProcessInfoRec        InfoRec;
  248.     ProcessSerialNumber    thePSN, *myPtr;
  249.     Str32                theName;
  250.  
  251.     foundBackgroundApp = false;
  252.     InfoRec.processInfoLength = sizeof( ProcessInfoRec );
  253.     InfoRec.processName = theName;
  254.     InfoRec.processAppSpec = &theSpec;
  255.     
  256.     thePSN.highLongOfPSN = 0;
  257.     thePSN.lowLongOfPSN = kNoProcess;
  258.  
  259.     while ( GetNextProcess( &thePSN ) != procNotFound )
  260.     {
  261.         theError = GetProcessInformation( &thePSN, &InfoRec );
  262.         if ( InfoRec.processSignature == 'asd9' )
  263.         {
  264.             foundBackgroundApp = true;
  265.             break;
  266.         }
  267.     }
  268.  
  269.     theError = FSMakeFSSpec( gParamBlockCopy->fileParam.ioVRefNum, gParamBlockCopy->fileParam.ioDirID, gParamBlockCopy->fileParam.ioNamePtr, &theSpec );
  270.  
  271.     if ( theError != noErr ) {
  272. #ifdef __DEBUG__
  273.       DebugStr( "\pUnable to create FSSpec in Extension." );
  274. #endif
  275.       return;
  276.     }
  277.  
  278.     if ( foundBackgroundApp )
  279.     {
  280.         myPtr = &thePSN;
  281.  
  282.         theError = AECreateDesc( typeProcessSerialNumber, ( Ptr )myPtr, sizeof( ProcessSerialNumber ), &theAddressDesc );
  283.  
  284.         theError = AECreateAppleEvent( 'asd9', 'newf', &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &theAppleEvent );
  285.  
  286.         theError = AEPutParamPtr( &theAppleEvent, keyDirectObject, typeFSS, &theSpec, sizeof( FSSpec ) );
  287.  
  288.         theError = AESend( &theAppleEvent, &theReply, kAENoReply, kAENormalPriority, kNoTimeOut, NIL, NIL );
  289.  
  290.         theError = AEDisposeDesc( &theAddressDesc );
  291.         theError = AEDisposeDesc( &theAppleEvent );
  292.     }
  293. }
  294.  
  295.  
  296. /**************************
  297.     DoFSPatchGestalt
  298. **************************/
  299.  
  300. static    pascal    OSErr    DoFSPatchGestalt( OSType theSelector, long *theResponse )
  301. {
  302.     short        theAction;
  303.     long        oldA4;
  304.     OSErr        theError = noErr;
  305.  
  306.     // Set up A4, so we can access our globals.
  307.     oldA4 = SetCurrentA4();
  308.  
  309.     //    The caller must request a specific selector    when calling our Gestalt routine.
  310.     switch ( theSelector )
  311.     {
  312.         case GESTALT_GET_INIT_GLOBALS:
  313.             //    Return the address of the array.
  314.             *theResponse = ( long )&gFSPatchGlobals;
  315.             break;
  316.  
  317.         case GESTALT_GET_ONE_GLOBALS:
  318.             //    Return the next array element.
  319.             *theResponse = ( long )&gFSPatchGlobals[ gLastRetrievedElement ];
  320.  
  321.             //    Update the index to the next element to send to the user.
  322.             gLastRetrievedElement++;
  323.  
  324.             if ( gLastRetrievedElement > MAX_NUM_FILES - 1 )
  325.                 gLastRetrievedElement = 0;
  326.  
  327.             break;
  328.  
  329.         case FS_SIGNATURE:
  330.             //    Return the address of this function.
  331. #ifndef powerc
  332.             *theResponse = ( long )gFSPatchProcPtr;
  333. #else
  334.             *theResponse = ( long )myGestaltUPP;
  335. #endif
  336.             break;
  337.  
  338.         case gestaltVersion:
  339.             //    Return the version of this INIT.
  340.             *theResponse = FS_VERSION_CURRENT;
  341.             break;
  342.  
  343.         case GESTALT_ADD_CALLBACK:
  344. #ifdef __DEBUG__
  345.     DebugStr( "\pCreating Routine Descriptor in DoFSPatchGestalt()..." );
  346. #endif
  347.             theAction = ( ( FWSubscribePtr )theResponse )->theAction;
  348.             switch ( theAction ) {
  349.                 case kCreateFlag:
  350.                     gCallbackProcPtr = NewRoutineDescriptor( ( ProcPtr )( ( FWSubscribePtr )theResponse )->theCallbackAddr, uppCreateFileProcInfo, kPowerPCISA );
  351.                     break;
  352.  
  353.                 default:
  354.                     break;
  355.             }
  356.  
  357.             break;
  358.  
  359.         case GESTALT_REMOVE_CALLBACK:
  360. #ifdef __DEBUG__
  361.     DebugStr( "\pRemoving Routine Descriptor in DoFSPatchGestalt()..." );
  362. #endif
  363.             theAction = ( ( FWSubscribePtr )theResponse )->theAction;
  364.             switch ( theAction ) {
  365.                 case kCreateFlag:
  366.                     if ( gCallbackProcPtr->routineRecords[ 0 ].procDescriptor == ( ProcPtr )( ( FWSubscribePtr )theResponse )->theCallbackAddr ) {
  367. #ifdef __DEBUG__
  368.                         DebugStr( "\pGracefully removing Routine Descriptor in DoFSPatchGestalt()..." );
  369. #endif
  370.                         DisposeRoutineDescriptor( ( UniversalProcPtr )gCallbackProcPtr );
  371.                         gCallbackProcPtr = nil;
  372.                     }
  373.  
  374.                     break;
  375.  
  376.                 default:
  377.                     break;
  378.             }
  379.  
  380.             break;
  381.  
  382.         default:
  383.             //    Don't understand the request.
  384.             theError = gestaltUnknownErr;
  385.             break;
  386.     }
  387.  
  388.     //    Required teardown.
  389.     SetA4(oldA4);
  390.  
  391.     return( theError );
  392. }
  393.  
  394.  
  395.